﻿/*
COPYRIGHT (C) 2011-2013 Raynald Messié

THIS FILE IS PART OF SCRUMPILOT.

SCRUMPILOT IS FREE SOFTWARE: YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF 
THE GNU LESSER GENERAL PUBLIC LICENSE VERSION v2.1 AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION.

SCRUMPILOT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY; WITHOUT
EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU LESSER
GENERAL PUBLIC LICENSE FOR MORE DETAILS.

YOU SHOULD HAVE RECEIVED A COPY OF THE GNU LESSER GENERAL PUBLIC LICENSE ALONG WITH SCRUMPILOT. 
IF NOT, SEE <HTTP://WWW.GNU.ORG/LICENSES/>.
*/

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using ScrumPilot.Domain.Helpers;
using ScrumPilot.Domain.Models;
using ScrumPilot.Helpers;
using ScrumPilot.TFSHelpers;
using WorkItem = ScrumPilot.Domain.Models.WorkItem;

namespace ScrumPilot.Domain.BPL
{
    public class WorkItemServices : BusinessProcessLayer
    {
        public WorkItemServices(TFSServices tfs) : base(tfs) { }

        public List<WorkItemProject> GetWorkItemsList(TFSServices tfs)
        {
            using (var unitOfWork = new UnitOfWork())
            {
                WorkItemState[] states = { WorkItemState.Todo, WorkItemState.InProgress, WorkItemState.Done };

                var projects = unitOfWork.ProjectRepository.GetFollowedProject();// DB.projects.Where(p => p.notuse == false).ToList();
                var lstRet = new List<WorkItemProject>(projects.Count);

                foreach (project project in projects)
                {
                    List<Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem> wil = tfs.GetWIList(project.name, project.currentsprint, false);
                    var lstClass = new List<WorkItemClass>(states.Count());

                    if (wil != null && wil.Count > 0)
                    {
                        lstClass.AddRange(states.Select(state => new WorkItemClass
                        {
                            Count = wil.Count(p => p.GetState() == state),
                            Name = state.ToString(),
                            State = state
                        }));
                    }
                    lstRet.Add(new WorkItemProject
                    {
                        ID = project.projectid,
                        Name = project.name,
                        CurrentSprint = project.currentsprint,
                        //   WorkItemClasses = lstClass.OrderBy(p => p.State).ToList()
                    });
                }
                return lstRet;
            }
        }

        public List<WorkItem> GetWorkItemsProject(Int32 projectID, Nullable<WorkItemState> state,
                                                         CultureInfo ci)
        {
            using (var unitOfWork = new UnitOfWork())
            {
                CurrentCulture = ci;

                project project = unitOfWork.ProjectRepository.GetById(projectID);
                List<Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem> wil = TFS.GetWIList(project.name, project.currentsprint, true);

                if (wil != null)
                {
                    if (state != null)
                        wil = wil.Where(p => p.GetState() == state).ToList();

                    var lstRet = new List<WorkItem>(wil.Count());
                    wil.ForEach(wie => lstRet.Add(wie.CastTFSWorkItem<WorkItem>(TFS, project.name, false)));
                    return lstRet;
                }

                return null;
            }
        }

        public List<WorkItem> GetWorkItemsUser(Int32 userId, CultureInfo ci)
        {
            CurrentCulture = ci;
            List<Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem> lst = GetWorkItemsExtUser(userId);
            return new List<WorkItem>(lst.Select(item => item.CastTFSWorkItem<WorkItem>(TFS, item.Project.Name, false)));
        }

        public List<WorkItem> GetScoringWorkItemsUser(Int32 userId, CultureInfo ci)
        {
            CurrentCulture = ci;
            using (var unitOfWork = new UnitOfWork())
            {
                user usr = unitOfWork.UserRepositery.GetById(userId);// DB.users.FirstOrDefault(p => p.userid == userId);
                if (usr != null)
                {
                    var qry = new TFSQuery(TFS.TfsWorkItemStore);
                    DateTime dStart = DateTimeHelpers.ScrumPilotStartPeriod(this.TFSParams.ScrumPilotScorePeriod, ci);
                    qry.GetScoredUserWorkItemList(usr.name, dStart, this.FollowedProjectsDictonary);

                    List<Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem> lst = qry.ScoredUserWorkItem;
                    var lstRet = new List<WorkItem>(lst.Count);
                    lstRet.AddRange(lst.Select(item => item.CastTFSWorkItem<WorkItem>(TFS, item.Project.Name, false)));
                    return lstRet;
                }
                return null;
            }
        }

        public List<Microsoft.TeamFoundation.WorkItemTracking.Client.WorkItem> GetWorkItemsExtUser(Int32 id)
        {
            using (var unitOfWork = new UnitOfWork())
            {
                user usr = unitOfWork.UserRepositery.GetById(id);
                if (usr != null)
                {
                    try
                    {
                        var tfsq = new TFSQuery(TFS.TfsWorkItemStore);
                        var wil = tfsq.GetWorkItemListForUser(this.FollowedProjectName,
                                                              new List<WorkItemState>
                                                              {
                                                                  WorkItemState.InProgress,
                                                                  WorkItemState.Reopen
                                                              },
                                                              new List<string>(), usr.name);

                        return (wil);
                    }
                    catch (Exception)
                    {
                        return null;
                    }
                }
                return null;
            }
        }

        public String GetSelectedProjects()
        {
            using (var unitOfWork = new UnitOfWork())
            {
                string s = unitOfWork.ProjectRepository.GetFollowedProject().Aggregate(string.Empty, (current, prj) => current + (prj.name + ", "));
                return s.Substring(0, s.Length - 2);
            }
        }
      
        public Boolean MoveWorkItem(int id, int destinationProjectId, TFSServices tfs)
        {
            if (destinationProjectId >= 0)
            {
                var sourceWorkItem = tfs.GetWorkItem(id, false); // Get workItem
                var destinationProject = tfs.GetProject(destinationProjectId); // get destionation project
                if (destinationProject.WorkItemTypes.Contains(sourceWorkItem.Type.Name)) // check if type of workitem is know into the destination
                {
                    var destWit = destinationProject.WorkItemTypes[sourceWorkItem.Type.Name];
                
                    var wim = sourceWorkItem.Copy(destWit, WorkItemCopyFlags.CopyFiles | WorkItemCopyFlags.CopyLinks);
                    var aList = sourceWorkItem.Validate();
                    if (aList.Count == 0)
                    {
                        if (tfs.SaveWorkItem(wim))
                        {
                            var ids = new List<int> { sourceWorkItem.Id };
                            // ReSharper disable IteratorMethodResultIsIgnored
                            tfs.TfsWorkItemStore.DestroyWorkItems(ids);
                            // ReSharper restore IteratorMethodResultIsIgnored
                            tfs.TfsWorkItemStore.RefreshCache();
                            tfs.TfsWorkItemStore.SyncToCache();
                        }
                    }
                }

            }
            return false;
        }

    }
}
